import React from 'react'
import Component, { mapStateToProps, mapDispatchToProps } from '../../../components/Component'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { message, Space, Button, Form, Row, Col, Modal } from 'antd'
import { ExclamationCircleOutlined } from '@ant-design/icons'
import moment from 'moment'
// import _ from 'loadsh'
import style from './Index.module.less'
import { CaseContext } from './context'
import { getDictinarys, getCaseTypeTree, getCaseDetail, getClaimItemConfig, getCauseActionTree, updateCaseRequest, createCaseRequest, unpassRequest } from './ajax/caseAjax'
import { awaitWrap, confirmAction, splitItem, strToNum } from '@js/tool'
import { paiedStatusList, defaultProcedure, simpleProcedure } from '@js/config'
import CaseInfoBlock from './components/CaseInfoBlock'
import PartyInfoBlock from './components/PartyInfoBlock'
import ClaimListBlock from './components/ClaimListBlock'
import UnpassModal from './components/UnpassModal'
import OriginClaim from './components/OriginClaim'
import { computeFee } from './fee'
const { confirm } = Modal

// 金融一到四类
const financeOneToFour = ['借贷', '金融不良资产转让与追偿', '信用卡', '担保']

class Main extends Component {
  state = {
    id: undefined,
    caseDetail: {},
    casenoDesc: undefined,
    acceptNo: undefined,
    serialNo: undefined,
    status: undefined,
    basis: undefined,
    dictionaries: {},
    typeTree: [],
    causeActionTree: [],
    claimItemConfig: [],
    claimItemFeeConfig: [],
    feeType: ['普通收费', '特殊收费'], // 案件收费方式可选项
    setClaimItemFeeConfig: this.setClaimItemFeeConfig.bind(this),
    computeFee: this.computeFee.bind(this),
    changeFeeTypeByCaseType: this.changeFeeTypeByCaseType.bind(this), // 根据案件类型修改收费方式可选项
    statisticDisputeAmount: this.statisticDisputeAmount.bind(this), // 汇总请求项的争议金额到总争议金额
    changeProcedure: this.changeProcedure.bind(this), // 根据案件总标的和案件类型改变仲裁程序
    changeFeeType: this.changeFeeType.bind(this), // 根据标的、仲裁程序等，改变收费方式
    setFeeByLog: this.setFeeByLog.bind(this), // 自定义仲裁费
    removeClaimItemFeeConfing: this.removeClaimItemFeeConfing.bind(this), // 删除某个仲裁请求配置项
    originClaim: null, // 仲裁原请求
    originClaimVisible: false, // 是否显示原请求
    setOriginClaim: this.setOriginClaim.bind(this), // 设置仲裁原请求
    cancelSplitClaim: this.cancelSplitClaim.bind(this), // 取消智能分项
    setOriginClaimVisible: this.setOriginClaimVisible.bind(this), // 设置原请求是否显示
    isPre: false, // 是否为预收案
    isModify: false, // 是否为修改案件信息
    disabled: false, // 是否禁止修改
    unpassVisible: false, // 不通过显示框
    noOld: true, // 是否为老案件
    forzen: false // 全部不准修改
  }

  formRef = React.createRef()

  // 设置请求项费用配置
  setClaimItemFeeConfig (claimItemFeeConfig, index = -1, rules = []) {
    this.setState({ claimItemFeeConfig }, () => {
      if (index === -1) {
        return false
      }
      const c = this.formRef.current
      const d = c.getFieldsValue()
      const item = {
        ...d.claim.items[index],
        dispute_amount: 0,
        fee_acceptance: 0,
        fee_processing: 0
      }
      rules.forEach(r => {
        item[r.key] = r.default_value ? Number(r.default_value) : 0
      })
      d.claim.items[index] = item
      c.setFieldsValue(d)
      this.statisticDisputeAmount()
      this.changeProcedure()
      this.changeFeeType()
      this.computeFee()
    })
  }

  // 删除某个仲裁请求配置项
  removeClaimItemFeeConfing (index) {
    const { claimItemFeeConfig } = this.state
    const list = [...claimItemFeeConfig]
    list.splice(index, 1)
    this.setState({ claimItemFeeConfig: list })
  }

  // 根据案件类型修改收费方式可选项
  changeFeeTypeByCaseType () {
    const c = this.formRef.current
    const casetype = c.getFieldValue(['casetype'])
    let feeType = []
    if (casetype.length === 0) {
      return false
    }
    const [one, two] = casetype
    if (one === '一般案件') {
      feeType = ['普通收费', '特殊收费']
    } else if (one === '金融案件') {
      if (financeOneToFour.indexOf(two) !== -1) {
        feeType = ['金融收费附录一', '金融收费附录二']
      } else {
        feeType = ['金融收费附录二']
      }
    }
    this.setState({ feeType })
  }

  // 汇总请求项的争议金额到总争议金额
  statisticDisputeAmount () {
    const c = this.formRef.current
    const d = c.getFieldsValue()
    let disputeAmount = 0
    d.claim.items.forEach(li => {
      if (li && li.dispute_amount) {
        disputeAmount += strToNum(li.dispute_amount)
      }
    })
    d.claim.dispute_amount = Number(disputeAmount.toFixed(2))
    c.setFieldsValue(d)
  }

  // 根据案件总标的和案件类型改变仲裁程序
  changeProcedure () {
    const c = this.formRef.current
    const d = c.getFieldsValue()
    const amount = d.claim.dispute_amount
    if (!d.casetype || d.casetype.length === 0) {
      return false
    }
    const [one, two] = d.casetype
    if (one === '一般案件') {
      d.procedure = amount < 500000 ? simpleProcedure : defaultProcedure
    } else if (one === '金融案件') {
      if (financeOneToFour.indexOf(two) === -1 && amount > 5000000) {
        d.procedure = defaultProcedure
      } else {
        d.procedure = simpleProcedure
      }
    }
    c.setFieldsValue(d)
  }

  // 根据标的、仲裁程序等，改变收费方式
  changeFeeType () {
    const c = this.formRef.current
    const d = c.getFieldsValue()
    if (!d.casetype || d.casetype.length === 0) {
      return false
    }
    const procedure = d.procedure
    const [one, two] = d.casetype
    if (one === '一般案件') {
      d.claim.fee_type = '普通收费'
    } else if (one === '金融案件') {
      if (financeOneToFour.indexOf(two) !== -1) {
        if (procedure.indexOf(defaultProcedure) === -1) {
          d.claim.fee_type = '金融收费附录一'
        } else {
          d.claim.fee_type = '金融收费附录二'
        }
      } else {
        d.claim.fee_type = '金融收费附录二'
      }
    }
    c.setFieldsValue(d)
  }

  // 计算费用
  computeFee () {
    const c = this.formRef.current
    const d = c.getFieldsValue()
    const claim = d.claim
    let disputeAmount = 0
    let acceptance = 0
    let processing = 0
    claim.items.forEach(li => {
      if (!li) {
        return false
      }
      if (li.dispute_amount) {
        disputeAmount += strToNum(li.dispute_amount)
      }
      if (li.fee_acceptance) {
        acceptance += strToNum(li.fee_acceptance)
      }
      if (li.fee_processing) {
        processing += strToNum(li.fee_processing)
      }
    })
    const procedure = d.procedure || ''
    let o
    if (procedure.indexOf(defaultProcedure) !== -1 && disputeAmount < 500000) {
      o = computeFee(500000, strToNum(claim.fee_type))
    } else {
      o = computeFee(Number(disputeAmount.toFixed(2)), strToNum(claim.fee_type))
    }
    if (disputeAmount === 0) {
      if (acceptance < o.fee_acceptance) {
        acceptance = o.fee_acceptance
      }
    } else {
      acceptance += o.fee_acceptance
    }
    processing += o.fee_processing
    claim.fee_acceptance = Number(acceptance.toFixed(2))
    claim.fee_processing = Number(processing.toFixed(2))
    claim.fee = Number((acceptance + processing).toFixed(2))
    claim.log = undefined
    c.setFieldsValue(d)
  }

  // 自定义费用
  setFeeByLog (data) {
    const c = this.formRef.current
    const d = c.getFieldsValue()
    d.claim = {
      ...d.claim,
      ...data
    }
    c.setFieldsValue(d)
  }

  // 前往案件详情
  toDetail () {
    const { id, casenoDesc, acceptNo, serialNo } = this.state
    const title = (casenoDesc || acceptNo || serialNo) ? `案件详情-${casenoDesc || acceptNo || serialNo}` : '案件详情'
    this.props.delWindow(this.props.id)
    this.props.addWindow({ id: `CaseDetail-${id}`, title, componentName: 'CaseDetail', forceRefresh: true, meta: { id, editable: true } })
  }

  // 前往待审核列表页
  toAuditList () {
    this.props.delWindow(this.props.id)
    this.props.addWindow({ id: 'AuditList', title: '待审核', componentName: 'AuditList', forceRefresh: false })
  }

  // 初始化字典
  async initDictionary () {
    const [e, d] = await awaitWrap(getDictinarys())
    if (e) {
      return message.warning(e.message)
    }
    this.setState({
      dictionaries: d
    })
  }

  // 初始化案件分类树
  async initDataTypeTree () {
    const [e, d] = await awaitWrap(getCaseTypeTree())
    if (e) {
      return message.warning(e.message)
    }
    this.setState({
      typeTree: d
    })
  }

  // 初始化案由树
  async initCauseActionTree () {
    const [e, d] = await awaitWrap(getCauseActionTree())
    if (e) {
      return message.warning(e.message)
    }
    this.setState({
      causeActionTree: d
    })
  }

  // 初始化请求项配置
  async initClaimItemConfig () {
    const [e, d] = await awaitWrap(getClaimItemConfig())
    if (e) {
      return message.warning(e.message)
    }
    this.setState({
      claimItemConfig: d
    })
  }

  // 创建案件
  async createCase (hide) {
    const [e, d] = await awaitWrap(createCaseRequest())
    if (e) {
      hide()
      return message.warning(e.message)
    }
    this.initData(d, hide)
  }

  // 初始化数据
  async initData (id, hide) {
    if (!id) {
      return false
    }
    const [e, d] = await awaitWrap(getCaseDetail(id))
    hide()
    if (e) {
      return message.error(e.message)
    }
    const noOld = d.accept_datetime > moment('2022-03-13 00:00:00')
    this.setState({
      id,
      caseDetail: d,
      status: d.status,
      casenoDesc: d.caseno_desc,
      basis: d.basis || '',
      serialNo: d.serial_no,
      acceptNo: d.accept_no,
      isModify: noOld && d.status && ['待审核', '已提交', '收案', '立案'].indexOf(d.status) === -1,
      disabled: noOld && d.status && paiedStatusList.indexOf(d.status) !== -1,
      noOld,
      forzen: noOld && ['待审核'].includes(d.status)
    }, () => {
      this.formatCaseDataToForm(d)
    })
  }

  // 格式化案件数据到表单
  formatCaseDataToForm (data) {
    const c = this.formRef.current
    data.applicants = this.formatPartyTag(data.applicants)
    data.respondents = this.formatPartyTag(data.respondents)
    this.formatClaim(data.claim)
    this.formatCaseType(data)
    if (data.status === '待审核') {
      this.formatDisputeaMountWhenNull(data)
    }
    data.accept_datetime = data.accept_datetime ? moment(data.accept_datetime) : moment()
    data.basis_signed_datetime = data.basis_signed_datetime ? moment(data.basis_signed_datetime) : undefined
    if (c) {
      c.setFieldsValue(data)
      if (data.status === '待审核') {
        this.changeProcedure()
        this.changeFeeType()
        this.computeFee()
      }
    }
  }

  // 格式化案件类型
  formatCaseType (data) {
    const casetype = []
    if (!data.casetype) {
      casetype.push('一般案件')
    } else {
      casetype.push(data.casetype)
      if (data.casesubtype) {
        casetype.push(data.casesubtype)
      }
    }
    data.casetype = casetype
  }

  // 格式化当事人标签
  formatPartyTag (list) {
    return list.map(li => {
      if (li.tag) {
        try {
          const tag = JSON.parse(li.tag)
          li = { ...li, ...tag }
        } catch (e) {
          console.error(e)
        }
      }
      return li
    })
  }

  // 展开子节点，生成一个扁平数组
  flatChildren (list) {
    let result = []
    list.forEach(li => {
      result.push(li)
      if (li.children && li.children.length) {
        result = [...result, ...this.flatChildren(li.children)]
      }
    })
    return result
  }

  // 格式化请求
  formatClaim (claim) {
    const { claimItemConfig } = this.state
    const flatClaimItemConfig = this.flatChildren(claimItemConfig)
    const titles = flatClaimItemConfig.map(li => li.title)
    const claimItemFeeConfig = []
    const keys = Object.keys(claim)
    if (keys.indexOf('dispute_amount') === -1) {
      const o = computeFee(0)
      claim.dispute_amount = 0
      claim.fee_acceptance = o.fee_acceptance
      claim.fee_processing = o.fee_processing
      claim.fee = o.fee
    }
    if (claim.items.length === 0) {
      claim.items = [{ type: '标的收费', dispute_amount: 0 }]
    }
    claim.items = claim.items.map(li => {
      const index = titles.indexOf(li.type)
      if (index === -1) {
        li.type = []
        claimItemFeeConfig.push([])
      } else {
        const config = flatClaimItemConfig[index]
        li.type = [...config.titles]
        claimItemFeeConfig.push(config.json_rule)
      }
      const s = {
        desc: li.desc,
        type: li.type,
        dispute_amount: li.dispute_amount,
        fee: li.fee,
        fee_acceptance: li.fee_acceptance,
        fee_processing: li.fee_processing
      }
      if (s.type[0] === '标的收费' && !s.dispute_amount) {
        s.dispute_amount = 0
      }
      return s
    })
    this.setClaimItemFeeConfig(claimItemFeeConfig)
  }

  // 提交事件
  async submitHandle (data, force) {
    const hide = message.loading('提交中', 120)
    if (!force) {
      // if (!this.validateFinanceCase(data)) {
      //   return message.warning('当事人未包含金融业企业，不符合金融收案规则，请更改案件类型')
      // }
      data = this.formatCaseData(data)
      if (!this.isPartyInfoFull()) {
        return message.warning('请先完善当事人的证件信息')
      }
      if (data.cause_action_ext && data.cause_action_ext === data.cause_action) {
        return message.warning('扩展案由不能与案由相同')
      }
      const items = data.claim.items
      for (let i = 0; i < items.length; i++) {
        const item = items[i]
        if (item.type === '标的收费' && !item.dispute_amount && !item.desc) {
          return message.warning('当仲裁请求的类型为标的收费时，争议金额和请求内容不能同时为默认值')
        }
      }
    } else {
      data.forcepassage = 1
    }
    const [e, d] = await awaitWrap(updateCaseRequest(this.state.id, data))
    hide()
    if (e) {
      return message.warning(e.message)
    }
    if (d) {
      return confirmAction(d.message, () => this.submitHandle(data, true))
    }
    this.toDetail()
  }

  // 格式化案件数据
  formatCaseData (data) {
    const [one, two] = data.casetype
    const s = this.state.status
    data.casetype = one
    if (two) {
      data.casesubtype = two
    }
    data.status = s && s !== '待审核' ? s : '已提交'
    data.accept_datetime = data.accept_datetime.format('YYYY-MM-DD HH:mm')
    this.formatCaseDataClaim(data)
    const c = data.claim
    data.dispute_amount = c.dispute_amount
    data.fee_acceptance = c.fee_acceptance
    data.fee_processing = c.fee_processing
    data.fee = c.fee_acceptance + c.fee_processing
    data.basis = data.basis ? data.basis : null
    if (data.basis_signed_datetime) {
      data.basis_signed_datetime = Math.floor(data.basis_signed_datetime.valueOf() / 1000)
    }
    delete data.applicants
    delete data.applicant_agents
    delete data.respondents
    delete data.respondents_agents
    return data
  }

  // 格式化提交中的案件请求数据
  formatCaseDataClaim (data) {
    data.claim.items.forEach(li => {
      const [one, two] = li.type
      if (two) {
        li.type = two
      } else {
        li.type = one
      }
    })
  }

  // 格式化争议金额
  formatDisputeaMountWhenNull (d) {
    const { claim } = d
    const { items } = claim
    if (!claim.dispute_amount) {
      claim.dispute_amount = 0
      items.forEach(item => {
        if (strToNum(item.dispute_amount)) {
          claim.dispute_amount += strToNum(item.dispute_amount)
        }
      })
      const o = computeFee(strToNum(claim.dispute_amount))
      claim.fee_acceptance = strToNum(claim.fee_acceptance)
      claim.fee_processing = strToNum(claim.fee_processing)
      claim.fee = strToNum(claim.fee)
      claim.fee_acceptance = o.fee_acceptance
      claim.fee_processing = o.fee_processing
      claim.fee = o.fee
    }
    return d
  }

  // 判断当事人的证件信息是否完善
  isPartyInfoFull () {
    const c = this.formRef.current
    const applicants = c.getFieldValue('applicants')
    const respondents = c.getFieldValue('respondents')
    const list = [...applicants, ...respondents]
    for (let i = 0; i < list.length; i++) {
      const li = list[i]
      if (!li.license) {
        return false
      }
    }
    return true
  }

  // 验证金融案件中的当事人是否符合规则
  validateFinanceCase (data) {
    const { applicants, respondents, casetype } = data
    if (casetype[0] !== '金融案件') {
      return true
    }
    const partys = [...applicants, ...respondents]
    for (let i = 0; i < partys.length; i++) {
      if (partys[i].finacial_company_type) {
        return true
      }
    }
    return false
  }

  // 二次确认审核通过
  confirmPass () {
    confirm({
      icon: <ExclamationCircleOutlined />,
      content: '您确认审核通过吗？',
      onOk: () => {
        const c = this.formRef.current
        c.submit()
      }
    })
  }

  // 审核不通过
  async unpassHandle (d) {
    const hide = message.loading('提交中', 120)
    const { id } = this.props.meta
    const [e] = await awaitWrap(unpassRequest(id, '审核不通过', d.remark))
    hide()
    if (e) {
      return message.warning(e.message)
    }
    this.setState({ unpassVisible: false }, () => {
      message.success('提交成功', 1, () => {
        this.toDetail()
      })
    })
  }

  // 设置原仲裁请求
  setOriginClaim () {
    const c = this.formRef.current
    let { claim } = c.getFieldsValue(['claim'])
    const item = claim.items[0]
    if (!item.desc) {
      return message.warning('要使用智能分项，仲裁请求不能为空')
    }
    try {
      const items = (splitItem(item.desc) || []).map(li => {
        return {
          desc: li,
          dispute_amount: 0,
          fee: 0,
          fee_acceptance: 0,
          fee_processing: 0,
          type: '标的收费'
        }
      })
      this.setState({
        originClaim: claim
      })
      claim = {
        ...claim,
        items
      }
      this.formatClaim(claim)
      c.setFieldsValue({ claim })
    } catch (e) {
      console.warn(e)
      message.warning('处理失败')
    }
  }

  // 取消拆分仲裁请求
  cancelSplitClaim () {
    this.setOriginClaimVisible(false)
    const c = this.formRef.current
    const claim = { ...this.state.originClaim }
    this.formatCaseDataClaim({ claim })
    this.formatClaim(claim)
    c.setFieldsValue({ claim })
    this.setState({
      originClaim: null
    })
  }

  // 设置原请求是否显示
  setOriginClaimVisible (visible) {
    this.setState({
      originClaimVisible: visible
    })
  }

  componentDidMount () {
    const hide = message.loading('加载中', 120)
    const id = this.props.meta.id
    Promise.all([this.initDictionary(), this.initDataTypeTree(), this.initClaimItemConfig(), this.initCauseActionTree()])
      .then(() => {
        if (id) {
          this.initData(id, hide)
        } else {
          this.createCase(hide)
        }
      })
      .catch(() => hide())
  }

  // 渲染案号
  renderCaseNo () {
    const { casenoDesc, acceptNo, serialNo } = this.state
    if (casenoDesc) {
      return (
        <Space>
          <span>案号 {casenoDesc}</span>
          <Button onClick={() => this.toDetail()}>返回</Button>
        </Space>
      )
    }
    return (
      <span>收案登记 {acceptNo || serialNo}</span>
    )
  }

  // 渲染操作按钮
  renderOperateBtn () {
    const { status } = this.state
    const res = []
    if (status) {
      res.push(<Button key={0} className={style.btn} onClick={() => status === '待审核' ? this.toAuditList() : this.toDetail()}>取消</Button>)
    }
    if (!status || !this.state.noOld || !['待审核', '已归档'].includes(status)) {
      res.push(<Button key={1} type='primary' htmlType='submit' className={style.btn}>提交</Button>)
    }
    if (status === '待审核') {
      res.push(<Button key={2} type='primary' className={style.btn} onClick={() => this.confirmPass()}>通过</Button>)
      res.push(<Button key={3} danger className={style.btn} onClick={() => this.setState({ unpassVisible: true })}>不通过</Button>)
    }
    return res
  }

  render () {
    const initialValues = {
      claim: {
        dispute_amount: 0,
        fee_acceptance: 0,
        fee_processing: 0,
        fee: 0,
        items: [{}]
      },
      basis: ''
    }
    return (
      <CaseContext.Provider value={this.state}>
        <div className={style.container}>
          <UnpassModal visible={this.state.unpassVisible} hide={() => this.setState({ unpassVisible: false })} decideHandle={d => this.unpassHandle(d)} />
          <OriginClaim claim={this.state.originClaim} visible={this.state.originClaimVisible} hide={() => this.setOriginClaimVisible(false)} />
          <div className={style['title-line']}>
            {this.renderCaseNo()}
          </div>
          <div className={style.form}>
            <Form ref={this.formRef} initialValues={initialValues} labelCol={{ flex: '120px' }} onFinish={d => this.submitHandle(d)}>
              <PartyInfoBlock caseFormRef={this.formRef} forzen={this.state.forzen} />
              <ClaimListBlock caseFormRef={this.formRef} forzen={this.state.forzen} />
              <CaseInfoBlock caseFormRef={this.formRef} forzen={this.state.forzen} />
              <Row>
                <Col span={6} />
                <Col span={6}>
                  <Space className={style['btn-line']} size='middle'>
                    {this.renderOperateBtn()}
                  </Space>
                </Col>
              </Row>
            </Form>
          </div>
        </div>
      </CaseContext.Provider>
    )
  }
}

Main.propTypes = {
  meta: PropTypes.object
}

Main.defaultProps = {
  meta: {
    id: undefined
  }
}

const mapState = mapStateToProps(function (state) {
  return {}
})

const mapDispatch = mapDispatchToProps(function (dispatch) {
  return {}
})

export default connect(mapState, mapDispatch)(Main)
